<!doctype html>
<html lang="en">

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>使用 sed 命令进行复制、剪切和粘贴 - 慧林淘友之达人助手</title>
    <meta name="HandheldFriendly" content="True">
    <meta name="MobileOptimized" content="320">
    <meta name="referrer" content="no-referrer">
    <meta name="description" content="慧林淘友之达人助手:交流与建议、BUG反馈。">
    <meta property="og:site_name" content="慧林淘友之达人助手" />
    <meta property="og:locale" content="nn_NO" />
    <meta property="og:type" content="article" />
    <meta property="og:url" content="https://www.lyhuilin.com/posts/linux_sed/" />
    <meta property="og:title" content="使用 sed 命令进行复制、剪切和粘贴" />
    <meta property="og:image" content="https://www.lyhuilin.com/apple-touch-icon.png" />
    <meta property="og:description" content="慧林淘友之达人助手:交流与建议、BUG反馈。" />

    

    <meta property="twitter:title" content="使用 sed 命令进行复制、剪切和粘贴" />
    <meta property="twitter:image" content="https://www.lyhuilin.com/apple-touch-icon.png" />
    <meta property="twitter:card" content="summary" />
    <meta property="twitter:description" content="慧林淘友之达人助手:交流与建议、BUG反馈。" />

    

    <link rel="canonical" href="https://www.lyhuilin.com/posts/linux_sed/">

    <link href="//cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css"
          rel="stylesheet"
          integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
          crossorigin="anonymous" />

    <link rel="stylesheet" href="https://www.lyhuilin.com/css/main.css" />

    

    

    <link rel="shortcut icon"
          href="https://www.lyhuilin.com/favicon.ico">

    <link href='' rel="alternate" type="application/rss+xml" title="慧林淘友之达人助手" />
    <link href="//fonts.googleapis.com/css?family=Fira+Code|Merriweather+Sans:400,700|Merriweather:400,700&display=swap"
    rel="stylesheet">

<style>
    :root {
        --font-code: "Fira Code", monospace;
        --font-content: "Merriweather", serif;
        --font-title: "Merriweather Sans", sans-serif;
    }
</style>
<script>
    var _hmt = _hmt || [];
    (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?d4f2e101b391ba33a192c215809ef30f";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>
  </head>

  <body>
    
  

<div class="my-4 my-md-5 header">
  <div class="container">
    <div class="row">
      <div class="col-auto offset-lg-1 d-none d-md-block">
        
          <a href="https://www.lyhuilin.com/">
            <img class="logo" src="https://www.lyhuilin.com/apple-touch-icon.png" alt="logo">
          </a>
        
      </div>
      <div class="col-auto align-self-center mr-auto">
        <a class="text-decoration-none" href="https://www.lyhuilin.com/">
          <h1 class="font-weight-bold name">
            慧林淘友之达人助手
          </h1>
        </a>

        <ul class="nav nav-primary">
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-home" href="/">
                
                Home
              </a>
            </li>
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-blog" href="https://3ae.cn">
                
                Blog
              </a>
            </li>
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-gitee" href="https://gitee.com/lyhuilin">
                
                Gitee
              </a>
            </li>
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-donations" href="/donations">
                
                Donations
              </a>
            </li>
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-Download" href="/download">
                
                Download
              </a>
            </li>
          
            <li class="nav-item">
              <a class="text-uppercase nav-link text-support" href="https://support.qq.com/products/65159">
                
                Support
              </a>
            </li>
          

          
        </ul>

        <ul class="nav nav-secondary">
          
        </ul>
      </div>
    </div>
  </div>
</div>


  <div class="content">
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-md-12 col-lg-10">
          <h1 class="mx-0 mx-md-4">
            使用 sed 命令进行复制、剪切和粘贴
          </h1>
          <div class="markdown">
            
  <blockquote>
<p>很少有 Unix 命令像 sed、grep 和 awk 一样出名，它们经常组合在一起，可能是因为它们具有奇怪的名称和强大的文本解析能力。它们还在一些语法和逻辑上有相似之处。虽然它们都能用于文本解析，但都有其特殊性。本文研究 sed 命令，它是一个 流编辑器。</p>
</blockquote>
<h3 id="安装-sed">安装 sed</h3>
<p>如果你使用的是 Linux、BSD 或 macOS，那么它们已经安装了 GNU 的或 BSD 的 sed。这些是原始 sed 命令的独特重新实现。虽然它们很相似，但也有一些细微的差别。本文已经在 Linux 和 NetBSD 版本上进行了测试，所以你可以使用你的计算机上找到的任何 sed，但是对于 BSD sed，你必须使用短选项（例如 -n 而不是 &ndash;quiet）。</p>
<p>GNU sed 通常被认为是功能最丰富的 sed，因此无论你是否运行 Linux，你可能都想要尝试一下。如果在 Ports 树中找不到 GNU sed（在非 Linux 系统上通常称为 gsed），你可以从 GNU 网站 下载源代码。 安装 GNU sed 的好处是，你可以使用它的额外功能，但是如果需要可移植性，还可以限制它以遵守 sed 的 POSIX 规范。</p>
<p>MacOS 用户可以在 MacPorts 或 Homebrew 上找到 GNU sed。</p>
<p>在 Windows 上，你可以通过 Chocolatey 来 安装 GNU sed。</p>
<h3 id="了解模式空间和保留空间">了解模式空间和保留空间</h3>
<p>sed 一次只能处理一行。因为它没有可视化模式，所以会创建一个 模式空间，这是一个内存空间，其中包含来自输入流的当前行（删除了尾部的任何换行符）。填充模式空间后，sed 将执行你的指令。当命令执行完时，sed 将模式空间中的内容打印到输出流，默认是 标准输出，但是可以将输出重定向到文件，甚至使用 <code>--in-place=.bak</code> 选项重定向到同一文件。</p>
<p>然后，循环从下一个输入行再次开始。</p>
<p>为了在遍历文件时提供一点灵活性，sed 还提供了保留空间（有时也称为 保留缓冲区），即 sed 内存中为临时数据存储保留的空间。你可以将保留空间当作剪贴板，实际上，这正是本文所演示的内容：如何使用 sed 复制/剪切和粘贴。</p>
<p>首先，创建一个示例文本文件，其内容如下：</p>
<pre><code>Line one
Line three
Line two
</code></pre>
<h3 id="复制数据到保留空间">复制数据到保留空间</h3>
<p>要将内容放置在 sed 的保留空间，使用 <code>h</code> 或 <code>H</code> 命令。小写的 <code>h</code> 告诉 sed 覆盖保留空间中的当前内容，而大写的 <code>H</code> 告诉 sed 将数据追加到保留空间中已经存在的内容之后。</p>
<p>单独使用，什么都看不到：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed --quiet -e <span style="color:#e6db74">&#39;/three/ h&#39;</span> example.txt
</span></span><span style="display:flex;"><span>$
</span></span></code></pre></div><p><code>--quiet</code>（缩写为 <code>-n</code>）选项禁止显示所有输出，但 sed 执行了我的搜索需求。在这种情况下，sed 选择包含字符串 three 的任何行，并将其复制到保留空间。我没有告诉 sed 打印任何东西，所以没有输出。</p>
<h3 id="从保留空间复制数据">从保留空间复制数据</h3>
<p>要了解保留空间，你可以从保留空间复制内容，然后使用 g 命令将其放入模式空间，观察会发生什么：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed -n -e <span style="color:#e6db74">&#39;/three/h&#39;</span> -e <span style="color:#e6db74">&#39;g;p&#39;</span> example.txt
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Line three
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><p>第一个空白行是因为当 sed 第一次复制内容到模式空间时，保留空间为空。</p>
<p>接下来的两行包含 <code>Line three</code> 是因为这是从第二行开始的保留空间。</p>
<p>该命令使用两个唯一的脚本（-e）纯粹是为了帮助提高可读性和组织性。将步骤划分为单独的脚本可能会很有用，但是从技术上讲，以下命令与一个脚本语句一样有效：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed -n -e <span style="color:#e6db74">&#39;/three/h ; g ; p&#39;</span> example.txt
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Line three
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><h3 id="将数据追加到模式空间">将数据追加到模式空间</h3>
<p><code>G</code> 命令会将一个换行符和保留空间的内容添加到模式空间。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed -n -e <span style="color:#e6db74">&#39;/three/h&#39;</span> -e <span style="color:#e6db74">&#39;G;p&#39;</span> example.txt
</span></span><span style="display:flex;"><span>Line one
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Line three
</span></span><span style="display:flex;"><span>Line three
</span></span><span style="display:flex;"><span>Line two
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><p>此输出的前两行同时包含模式空间（<code>Line one</code>）的内容和空的保留空间。接下来的两行与搜索文本（<code>three</code>）匹配，因此它既包含模式空间又包含保留空间。第三行的保留空间没有变化，因此在模式空间（<code>Line two</code>）的末尾是保留空间（仍然是 <code>Line three</code>）。</p>
<h3 id="用-sed-剪切和粘贴">用 sed 剪切和粘贴</h3>
<p>现在你知道了如何将字符串从模式空间转到保留空间并再次返回，你可以设计一个 sed 脚本来复制、删除，然后在文档中粘贴一行。例如，将示例文件的 Line three 挪至第三行，sed 可以解决这个问题：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed -n -e <span style="color:#e6db74">&#39;/three/ h&#39;</span> -e <span style="color:#e6db74">&#39;/three/ d&#39;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>-e <span style="color:#e6db74">&#39;/two/ G;p&#39;</span> example.txt
</span></span><span style="display:flex;"><span>Line one
</span></span><span style="display:flex;"><span>Line two
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><ul>
<li>第一个脚本找到包含字符串 <code>three</code> 的行，并将其从模式空间复制到保留空间，替换当前保留空间中的任何内容。</li>
<li>第二个脚本删除包含字符串 <code>three</code> 的任何行。这样就完成了与文字处理器或文本编辑器中的 剪切 动作等效的功能。</li>
<li>最后一个脚本找到包含字符串 <code>two</code> 的行，并将保留空间的内容_追加_到模式空间，然后打印模式空间。</li>
</ul>
<p>任务完成。</p>
<h3 id="使用-sed-编写脚本">使用 sed 编写脚本</h3>
<p>再说一次，使用单独的脚本语句纯粹是为了视觉和心理上的简单。剪切和粘贴命令作为一个脚本同样有效：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ sed -n -e <span style="color:#e6db74">&#39;/three/ h ; /three/ d ; /two/ G ; p&#39;</span> example.txt
</span></span><span style="display:flex;"><span>Line one
</span></span><span style="display:flex;"><span>Line two
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><p>它甚至可以写在一个专门的脚本文件中：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e">#!/usr/bin/sed -nf
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>/three/h
</span></span><span style="display:flex;"><span>/three/d
</span></span><span style="display:flex;"><span>/two/ G
</span></span><span style="display:flex;"><span>p
</span></span></code></pre></div><p>要运行该脚本，将其加入可执行权限，然后用示例文件尝试：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>$ chmod +x myscript.sed
</span></span><span style="display:flex;"><span>$ ./myscript.sed example.txt
</span></span><span style="display:flex;"><span>Line one
</span></span><span style="display:flex;"><span>Line two
</span></span><span style="display:flex;"><span>Line three
</span></span></code></pre></div><p>当然，你需要解析的文本越可预测，则使用 sed 解决问题越容易。发明 sed 操作（例如复制和粘贴）的“配方”通常是不切实际的，因为触发操作的条件可能因文件而异。但是，你对 sed 命令的使用越熟练，就越容易根据需要解析的输入来设计复杂的动作。</p>
<p>重要的事情是识别不同的操作，了解 sed 何时移至下一行，并预测模式和保留空间包含的内容。</p>
<p>sed 很复杂。虽然它只有十几个命令，但它灵活的语法和原生功能意味着它充满了无限的潜力。</p>
<h3 id="参考">参考</h3>
<p>How to use the Linux sed command <a href="https://opensource.com/article/21/3/sed-cheat-sheet">[1]</a></p>
<p>使用 sed 命令进行复制、剪切和粘贴   <a href="https://linux.cn/article-13417-1.html">[2]</a></p>



          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="my-4 footer">
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-sm-12 col-md-6 col-lg-5">
        <div class="mx-0 mx-md-4 mb-2 text-center text-md-start">
          
            <div>
              <a class="mx-1 mr-md-2 ml-md-0 " href="https://beian.miit.gov.cn/">
                
                豫ICP备13005404号
              </a>
            </div>
          

          
            
              <a href="https://www.lyhuilin.com">白菜林</a>
            
          
        </div>
      </div>
      <div class="col-sm-12 col-md-6 col-lg-5">
        <div class="mx-0 mx-md-4 text-center text-md-end">
          

          

          
  <a href="https://github.com/clin003"
     target="_blank"
     class="mx-1 ml-md-2 mr-md-0 icon"
     aria-label="GitHub">

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414">
      <path d="M8 0C3.58 0 0 3.582 0 8c0 3.535 2.292 6.533 5.47 7.59.4.075.547-.172.547-.385 0-.19-.007-.693-.01-1.36-2.226.483-2.695-1.073-2.695-1.073-.364-.924-.89-1.17-.89-1.17-.725-.496.056-.486.056-.486.803.056 1.225.824 1.225.824.714 1.223 1.873.87 2.33.665.072-.517.278-.87.507-1.07-1.777-.2-3.644-.888-3.644-3.953 0-.873.31-1.587.823-2.147-.09-.202-.36-1.015.07-2.117 0 0 .67-.215 2.2.82.64-.178 1.32-.266 2-.27.68.004 1.36.092 2 .27 1.52-1.035 2.19-.82 2.19-.82.43 1.102.16 1.915.08 2.117.51.56.82 1.274.82 2.147 0 3.073-1.87 3.75-3.65 3.947.28.24.54.73.54 1.48 0 1.07-.01 1.93-.01 2.19 0 .21.14.46.55.38C13.71 14.53 16 11.53 16 8c0-4.418-3.582-8-8-8"/>
    </svg>
  </a>


          

          

          

          

          

          
  <a href="mailto:hi@lyhuilin.com"
     class="mx-1 ml-md-2 mr-md-0 icon"
     aria-label="Email">

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 16">
      <path d="M0 4v8c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1zm13 0L7 9 1 4h12zM1 5.5l4 3-4 3v-6zM2 12l3.5-3L7 10.5 8.5 9l3.5 3H2zm11-.5l-4-3 4-3v6z"/>
    </svg>
  </a>


          <a href=''
   class="mx-1 ml-md-2 mr-md-0 icon"
   aria-label="RSS">

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414">
    <path d="M12.8 16C12.8 8.978 7.022 3.2 0 3.2V0c8.777 0 16 7.223 16 16h-3.2zM2.194 11.61c1.21 0 2.195.985 2.195 2.196 0 1.21-.99 2.194-2.2 2.194C.98 16 0 15.017 0 13.806c0-1.21.983-2.195 2.194-2.195zM10.606 16h-3.11c0-4.113-3.383-7.497-7.496-7.497v-3.11c5.818 0 10.606 4.79 10.606 10.607z"/>
  </svg>
</a>


          
        </div>
      </div>
    </div>
  </div>
</div>



    <script src="//cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4"
            crossorigin="anonymous"></script>

    

    

    

    
    
  </body>

</html>
